﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using iTunesLib;
using MinhUtils;
using System.Text.RegularExpressions;
using System.IO;
using System.Diagnostics;
using System.Web;

namespace iTunesLyricsAdder
{
    public partial class MainForm : Form
    {
        private bool _stopSearching = false;
        private StreamWriter _logWriter;
        private string _logFileName = "log_ila.txt";
        private int _lyricsSrcIdx = 0;
        
        public MainForm()
        {
            InitializeComponent();

            cbxLyricsSource.Items.Add("azlyrics.com");
            cbxLyricsSource.Items.Add("mp3lyrics.org");
            cbxLyricsSource.Items.Add("lyrics007.com");
            cbxLyricsSource.SelectedIndex = 2;
        }

        private void btnSearchAndAddLyrics_Click(object sender, EventArgs e)
        {
            lblProgress.Text = @"0%";
            pgbSearchAndAddProgress.Minimum = 0;
            pgbSearchAndAddProgress.Maximum = 100;
            pgbSearchAndAddProgress.Value = 0;
            btnSearchAndAddLyrics.Enabled = false;
            btnStopSearching.Enabled = true;
            cbxLyricsSource.Enabled = false;
            _stopSearching = false;
            _lyricsSrcIdx = cbxLyricsSource.SelectedIndex;

            new Thread(new ThreadStart(SearchAddLyrics)).Start();
        }

        private void SearchAddLyrics()
        {
            //search and add lyrics
            IITTrackCollection trackCol = new iTunesApp().LibraryPlaylist.Tracks;
            int total = trackCol.Count;
            int processed = 0;
            int added = 0;
            string status = string.Empty;

            foreach (IITTrack track in trackCol)
            {
                if (_stopSearching)
                    break;

                try
                {
                    string lyric = ((IITFileOrCDTrack)track).Lyrics;

                    if (string.IsNullOrEmpty(lyric) && chbOnlySearchAndAddLyricsToSongsWihoutOnes.Checked)
                    {
                        lyric = GetLyrics(track.Artist, track.Name);

                        if (lyric.Equals(string.Empty))
                        {
                            status = "lyric not found";
                        }
                        else
                        {
                            ((IITFileOrCDTrack)track).Lyrics = lyric;
                            added++;

                            status = "lyric added";
                        }
                    }
                    else
                    {
                        status = "skipped";
                    }

                    if (status.Equals("lyric added"))
                        WriteLog(string.Format("{0} - {1} - {2}", track.Name, track.Artist, status));

                    processed++;
                    Action<int, int> showProgress = ShowProgress;
                    Invoke(showProgress, new object[] { processed, total });
                }
                catch { }
            }

            Action<Control, bool> enableControl = FormUtil.EnableControl;
            Invoke(enableControl, new object[] { btnSearchAndAddLyrics, true });
            Invoke(enableControl, new object[] { btnStopSearching, false });
            Invoke(enableControl, new object[] { cbxLyricsSource, true });

            Action<Label, string> setLabelText = FormUtil.SetLabelText;
            Invoke(setLabelText, new object[] { lblProgress, string.Format("{0} lyric(s) have been added", added) });

            //open log file
            Process.Start(_logFileName);
        }

        private string GetLyrics(string artist, string title)
        {
            string lyric = string.Empty;

            if (_lyricsSrcIdx == 0) //azlyrics.com
            {
                artist = artist.ToLower().Replace(" ", "");
                title = title.ToLower().Replace(" ", "").Replace("'", "");

                string url = string.Format("http://www.azlyrics.com/lyrics/{0}/{1}.html", artist, title);
                string webContent = NetUtil.DownloadContent(url);
                string pattern = "(?<=<!-- start of lyrics -->)((.|\n)*)(?=<!-- end of lyrics -->)";

                Match match = Regex.Match(webContent, pattern);

                lyric = match.Value.Replace("<br/>", "").Replace("<br>", "").Replace("<i>", "").Replace("</i>", "");
            }
            else if (_lyricsSrcIdx == 1) //mp3lyrics.org
            {
                //artist = "All 4 One";
                //title = "I swear";
                string category = artist.Substring(0, 1);

                if (char.IsNumber(category, 0))
                    category = "0-9";

                artist = artist.ToLower().Replace(" ", "-");
                title = title.ToLower().Replace(" ", "-").Replace("'", "-");

                string url = string.Format("http://www.mp3lyrics.org/{0}/{1}/{2}/", category, artist, title);
                string webContent = NetUtil.DownloadContent(url);
                string pattern = "(?<=gn_lyricsB>)((.|\n)*)(?=</span></div></div>)";

                Match match = Regex.Match(webContent, pattern);

                lyric = HttpUtility.HtmlDecode(match.Value);
                lyric = lyric.Replace("<br/>", "").Replace("<br>", "").Replace("<i>", "").Replace("</i>", "").Replace("<u>", "").Replace("</u>", "");
            }
            else if (_lyricsSrcIdx == 2) //lyrics007.com
            {
                //artist = "Michael Learns To Rock";
                //title = "Home To You";

                string url = string.Format("http://www.lyrics007.com/{0}%20Lyrics/{1}%20Lyrics.html", artist, title);
                string webContent = NetUtil.DownloadContent(url);
                string pattern = "(?<=<br><br><br>)[^<]((.|\n)*)(?=<br><br><script)";

                lyric = Regex.Match(webContent, pattern).Value;
                lyric = lyric.Replace("<br/>", "").Replace("<br>", "").Replace("<BR>", "").Replace("<BR/>", "");
            }
            else
            {
            }

            return lyric;
        }

        private void ShowProgress(int processed, int total)
        {
            double percentageCompleted = Common.GetPercentageDouble(processed, total);
            
            lblProgress.Text = processed + "/" + total + " files processed.";
            lblProgressPercentage.Text = percentageCompleted + "%";
            pgbSearchAndAddProgress.Value = (int)percentageCompleted;
            this.Text = percentageCompleted + "%";
        }

        private void btnStopSearching_Click(object sender, EventArgs e)
        {
            btnStopSearching.Enabled = false;
            _stopSearching = true;
        }

        private void WriteLog(string logMessage)
        {
            //http://msdn.microsoft.com/en-us/library/3zc0w663.aspx
            try
            {
                using (_logWriter = System.IO.File.AppendText(_logFileName))
                {
                    lock (_logWriter)
                    {
                        //_logWriter.Write("\r\nLog Entry : ");
                        //_logWriter.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
                        _logWriter.WriteLine("{0}", logMessage);
                        //_logWriter.WriteLine("-------------------------------");
                        // Update the underlying file.
                        _logWriter.Flush();

                        // Close the writer and underlying file.
                        _logWriter.Close();
                    }
                }
            }
            catch (System.IO.IOException)
            {
                System.Threading.Thread.Sleep(1000);
                WriteLog(logMessage);
            }
        }
    }
}
